package com.shell.customer.base.rx;

import com.shell.bee.base.exception.UnCheckMsgException;
import com.shell.bee.base.utils.StringUtil;
import com.shell.bee.esign.vo.EsignAuthResponse;
import com.shell.customer.accreditation.vo.UserVo;
import com.shell.customer.base.CusEvent;
import com.shell.customer.base.service.CusRecService;
import com.shell.customer.base.vo.CusRecVo;
import com.shell.customer.esign.service.EsignAcctTxService;
import com.shell.customer.esign.service.EsignAuthTxService;
import com.shell.customer.po.CusAcct;
import com.shell.customer.po.CusRec;
import com.shell.customer.util.CustomerUtil;
import com.shell.framework.rx.OnErrorNotImplementedSubscriber;
import com.shell.governor.user.vo.PubUserVo;
import com.timevale.esign.sdk.tech.bean.result.AddAccountResult;
import com.timevale.esign.sdk.tech.bean.result.Result;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class EsignOpenAcctForCusSubscriber extends OnErrorNotImplementedSubscriber<CusEvent> {
	@Autowired
	private EsignAcctTxService esignAcctTxService;
	@Autowired
	private EsignAuthTxService esignAuthTxService;
	@Autowired
	private CusRecService cusRecService;

	public void onApplicationEvent(CusEvent event) {
		if (!CustomerUtil.onEsign()) {
			return;
		}
		CusRecVo cusRecVo = event.getCusRecVo();
		PubUserVo pubUser = event.getUser();
		UserVo user = new UserVo();
		BeanUtils.copyProperties(pubUser, user);
		CusRec cus = null;
		if (!cusRecVo.isOperator()) {
			try {
				authAdmin(user);

				cus = (CusRec) this.cusRecService.selectByKey(cusRecVo.getCusId());

				String serviceId = authCus(cus);

				CusAcct cusAcct = event.getCusAcct();
				if (cusAcct.isPayAuth()) {
					cusAcct.setCusId(cus.getCusId());

					authCusBank(cusAcct, serviceId);

					cus.setCusState("6");
					this.cusRecService.updateNotNull(cus);
				}
			} catch (Exception e) {
				throw new UnCheckMsgException("��������������e������" + e.getMessage());
			}
		}
		if (event.isAdd()) {
			openEsignAccts(cusRecVo, user);
		} else {
			updateEsignAccts(cusRecVo, cus, user);
		}
	}

	private void authCusBank(CusAcct cusAcct, String serviceId) throws Exception {
		EsignAuthResponse payResponse = this.esignAuthTxService.toPay(cusAcct, serviceId);
		if (payResponse.getErrCode() != 0) {
			throw new UnCheckMsgException(payResponse.getMsg());
		}
	}

	private String authCus(CusRec cus) throws Exception {
		EsignAuthResponse response = this.esignAuthTxService.authBaseInfo(cus);
		if (response.getErrCode() != 0) {
			throw new UnCheckMsgException(response.getMsg());
		}
		return response.getServiceId();
	}

	private void authAdmin(UserVo user) throws Exception {
		EsignAuthResponse response = this.esignAuthTxService.personTelecomAuth(user);
		if (response.getErrCode() != 0) {
			throw new UnCheckMsgException(response.getMsg());
		}
	}

	private void updateEsignAccts(CusRecVo cusRecVo, CusRec cus, UserVo user) {
		if (cus == null) {
			cus = (CusRec) this.cusRecService.selectByKey(cusRecVo.getCusId());
		}
		checkCusSocCrCode(cusRecVo, cus);
		if (checkCusSocCrCode(cusRecVo, cus)) {
			openEsignAccts(cusRecVo, user);
		} else if (checkCusName(cusRecVo, cus)) {
			Result result = this.esignAcctTxService.updateCustAcct(cusRecVo, user);
			if (result.getErrCode() != 0) {
				throw new UnCheckMsgException("����e������������������" + result.getMsg());
			}
		}
	}

	private boolean checkCusName(CusRecVo cusRecVo, CusRec cus) {
		String oriCusName = cus.getCusName();
		String newCusName = cusRecVo.getCusName();
		if ((StringUtil.notEmpty(oriCusName)) && (StringUtil.notEmpty(newCusName))
				&& (!oriCusName.equals(newCusName))) {
			return true;
		}
		return false;
	}

	private boolean checkCusSocCrCode(CusRecVo cusRecVo, CusRec cus) {
		String oriSocCrCode = cus.getSocCrCode();
		String newSocCrCOde = cusRecVo.getSocCrCode();
		if ((StringUtil.notEmpty(oriSocCrCode)) && (StringUtil.notEmpty(newSocCrCOde))
				&& (!oriSocCrCode.equals(newSocCrCOde))) {
			return true;
		}
		return false;
	}

	private void openEsignAccts(CusRecVo cusRecVo, UserVo user) {
		CusRec cusRec = new CusRec();
		BeanUtils.copyProperties(cusRecVo, cusRec);
		AddAccountResult result = this.esignAcctTxService.openCustAcct(cusRec, user);
		if (result.getErrCode() != 0) {
			throw new UnCheckMsgException("����e������������������" + result.getMsg());
		}
	}
}
